package com.atguigu.gmall.cart.service;

import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.atguigu.gmall.cart.mapper.CartInfoMapper;
import com.atguigu.gmall.common.util.AuthContextHolder;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.product.SkuInfo;
import com.atguigu.gmall.product.client.ProductFeignClient;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author sunjipu
 * @create 2020-04-17 16:02
 */
@Service
public class CartServiceImpl implements CartService {











    @Autowired
    private CartInfoMapper cartInfoMapper;
    @Autowired
    private ProductFeignClient productFeignClient;
    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public CartInfo addToCart(Long skuId, Integer skuNum,String userId) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes)
                RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        //用户ID
         userId = AuthContextHolder.getUserId(request);
        if (StringUtils.isEmpty(userId)) {
            //临时用户ID
            userId = AuthContextHolder.getUserTempId(request);
        }
        CartInfo cartInfo = cartInfoMapper.selectOne(
                new QueryWrapper<CartInfo>()
                        .eq("sku_id", skuId)
                        .eq("user_id", userId));
        if (null != cartInfo) {
            cartInfo.setSkuNum(cartInfo.getSkuNum() + skuNum);
            //查实时价格
            BigDecimal skuPrice = productFeignClient.getSkuPrice(skuId);
            cartInfo.setSkuPrice(skuPrice);
            cartInfo.setIsChecked(1);
            cartInfoMapper.updateById(cartInfo);
        } else {
            cartInfo = new CartInfo();
            SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);
            cartInfo.setSkuNum(skuNum);
            cartInfo.setSkuId(skuId);
            cartInfo.setUserId(userId);
            cartInfo.setCartPrice(skuInfo.getPrice());
            cartInfo.setImgUrl(skuInfo.getSkuDefaultImg());
            cartInfo.setSkuName(skuInfo.getSkuName());
            cartInfo.setSkuPrice(skuInfo.getPrice());
            cartInfoMapper.insert(cartInfo);
        }
        return cartInfo;
    }


    @Override
    public List<CartInfo> cartList(String userId, String userTempId) {
        //判断是否已经登录
            if (!StringUtils.isEmpty(userId)) {
                //登录
                //临时用户的购物车  用户的购物车
                return mergeCartList(this.cartList(userId), this.cartList(userTempId), userTempId,userId);
            } else {
                //未登录
                //临时用户的购物车
                return this.cartList(userTempId);
        }
    }

    private List<CartInfo> mergeCartList(List<CartInfo> cartListUserId, List<CartInfo> cartListUserTempId
            , String userTempId,String userId) {
        if(!CollectionUtils.isEmpty(cartListUserId)){
            if(!CollectionUtils.isEmpty(cartListUserTempId)){
                Map<Long, CartInfo> cartInfoUserIdMap = cartListUserId.stream()
                        .collect(Collectors.toMap(CartInfo::getSkuId, cartInfo -> cartInfo));
                cartListUserTempId.forEach((cartInfo) -> {
                    Long skuId = cartInfo.getSkuId();
                    if(cartInfoUserIdMap.containsKey(skuId)){
                        CartInfo cartInfo1 = cartInfoUserIdMap.get(skuId);
                        cartInfo1.setSkuNum(cartInfo1.getSkuNum() + cartInfo.getSkuNum());
                        cartInfoMapper.updateById(cartInfo1);
                    }else{
                        cartInfoUserIdMap.put(cartInfo.getSkuId(),cartInfo);
                        cartInfo.setUserId(userId);
                        cartInfoMapper.updateById(cartInfo);
                    }

                });
                List<Long> ids = cartListUserTempId.stream().map(CartInfo::getId).collect(Collectors.toList());
                cartInfoMapper.deleteBatchIds(ids);
                Collection<CartInfo> values = cartInfoUserIdMap.values();
                return new ArrayList<>(values);
            }else{
                return cartListUserId;
            }
        }else{
            if(!CollectionUtils.isEmpty(cartListUserTempId)){
                CartInfo cartInfo = new CartInfo();
                cartInfo.setUserId(userId);
                cartInfoMapper.update(cartInfo,
                        new QueryWrapper<CartInfo>()
                                .eq("user_id",userTempId));
                return cartListUserTempId;
            }else{
                return new ArrayList<CartInfo>();
            }
        }
    }


    private List<CartInfo> cartList(String userId) {
        List<CartInfo> cartInfoList = cartInfoMapper.selectList(new QueryWrapper<CartInfo>().eq("user_id", userId));
        //更新价格
        if(!CollectionUtils.isEmpty(cartInfoList)){
            cartInfoList.forEach(cart -> {
                BigDecimal skuPrice = productFeignClient.getSkuPrice(cart.getSkuId());
                cart.setSkuPrice(skuPrice);
            });
        }
        return cartInfoList;
    }
    @Override
    public void checkCart(String userId, Integer isChecked, Long skuId) {
        // update cartInfo set isChecked=? where  skuId = ? and userId=？
        // 修改数据库
        // 第一个参数表示修改的数据，第二个参数表示条件
        CartInfo cartInfo = new CartInfo();
        cartInfo.setIsChecked(isChecked);
        QueryWrapper queryWrapper = new QueryWrapper<CartInfo>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("sku_id", skuId);
        cartInfoMapper.update(cartInfo, queryWrapper);

    }

    @Override
    public void deleteCart(Long skuId, String userId) {
        String cartKey =getCartKey(userId);

        // 判断缓存中是否有cartKey，先加载数据库中的数据放入缓存！
        if (!redisTemplate.hasKey(cartKey)) {
            //loadCartCache(userId);
        }

        cartInfoMapper.delete(new QueryWrapper<CartInfo>()
                .eq("user_id", userId)
                .eq("sku_id", skuId));

        //获取缓存对象
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        hashOperations.delete(skuId.toString());
    }

    @Override
    public List<CartInfo> getCartCheckedList(String userId) {
        List<CartInfo> cartInfoList = new ArrayList<>();

        // 定义key user:userId:cart
        String cartKey = this.getCartKey(userId);
        List<CartInfo> cartCachInfoList = redisTemplate.opsForHash().values(cartKey);
        if (null != cartCachInfoList && cartCachInfoList.size() > 0) {
            for (CartInfo cartInfo : cartCachInfoList) {
                // 获取选中的商品！
                if (cartInfo.getIsChecked().intValue() == 1) {
                    cartInfoList.add(cartInfo);
                }
            }
        }
        return cartInfoList;
    }

    private String getCartKey(String userId) {
        return "";
    }

}
